{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 10 ``Numpy`` 中的比较和Fancy Indexing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fancy Indexing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])"
     },
     "metadata": {},
     "execution_count": 2
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "x = np.arange(16)\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "3"
     },
     "metadata": {},
     "execution_count": 3
    }
   ],
   "source": [
    "x[3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([3, 4, 5, 6, 7, 8])"
     },
     "metadata": {},
     "execution_count": 4
    }
   ],
   "source": [
    "x[3:9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([3, 5, 7])"
     },
     "metadata": {},
     "execution_count": 5
    }
   ],
   "source": [
    "# 切片的方式必须等长\n",
    "x[3:9:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "[3, 5, 8]"
     },
     "metadata": {},
     "execution_count": 41
    }
   ],
   "source": [
    "[x[3], x[5], x[8]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([3, 5, 8])"
     },
     "metadata": {},
     "execution_count": 42
    }
   ],
   "source": [
    "# 所以numpy提供了非常方便的取出任意索引组的方法\n",
    "ind = [3, 5, 8]\n",
    "x[ind]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[0, 2],\n       [1, 3]])"
     },
     "metadata": {},
     "execution_count": 8
    }
   ],
   "source": [
    "# 可以二维数组，二维矩阵对应的是每一个索引\n",
    "ind = np.array([[0, 2], [1, 3]])\n",
    "x[ind]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fancy Indexing 应用在二维数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[ 0,  1,  2,  3],\n       [ 4,  5,  6,  7],\n       [ 8,  9, 10, 11],\n       [12, 13, 14, 15]])"
     },
     "metadata": {},
     "execution_count": 9
    }
   ],
   "source": [
    "X = x.reshape(4, -1)\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([ 1,  6, 11])"
     },
     "metadata": {},
     "execution_count": 43
    }
   ],
   "source": [
    "# 感兴趣的是(0, 1),(1, 2),(2, 3)\n",
    "row = np.array([0, 1, 2])\n",
    "col = np.array([1, 2, 3])\n",
    "X[row, col]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([1, 2, 3])"
     },
     "metadata": {},
     "execution_count": 11
    }
   ],
   "source": [
    "# (0, 1), (0, 2), (0, 3)\n",
    "X[0, col]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[1, 2, 3],\n       [5, 6, 7]])"
     },
     "metadata": {},
     "execution_count": 12
    }
   ],
   "source": [
    "# (0, 1), (0, 2), (0, 3), (1, 1), (1, 2), (1, 3)\n",
    "X[:2, col]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "col = [True, False, True, True]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([0, 2, 3])"
     },
     "metadata": {},
     "execution_count": 14
    }
   ],
   "source": [
    "# 对true的部分感兴趣\n",
    "# 这种用法非常重要\n",
    "X[0, col]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ``numpy.array`` 的比较"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])"
     },
     "metadata": {},
     "execution_count": 15
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([ True,  True,  True, False, False, False, False, False, False,\n       False, False, False, False, False, False, False])"
     },
     "metadata": {},
     "execution_count": 16
    }
   ],
   "source": [
    "# x中所有元素和3相比\n",
    "x < 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([False, False, False, False,  True,  True,  True,  True,  True,\n        True,  True,  True,  True,  True,  True,  True])"
     },
     "metadata": {},
     "execution_count": 17
    }
   ],
   "source": [
    "x > 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([ True,  True,  True,  True, False, False, False, False, False,\n       False, False, False, False, False, False, False])"
     },
     "metadata": {},
     "execution_count": 18
    }
   ],
   "source": [
    "x <= 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([False, False, False,  True,  True,  True,  True,  True,  True,\n        True,  True,  True,  True,  True,  True,  True])"
     },
     "metadata": {},
     "execution_count": 19
    }
   ],
   "source": [
    "x >= 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([False, False, False,  True, False, False, False, False, False,\n       False, False, False, False, False, False, False])"
     },
     "metadata": {},
     "execution_count": 20
    }
   ],
   "source": [
    "x == 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([ True,  True,  True, False,  True,  True,  True,  True,  True,\n        True,  True,  True,  True,  True,  True,  True])"
     },
     "metadata": {},
     "execution_count": 21
    }
   ],
   "source": [
    "x != 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([False, False, False, False,  True, False, False, False, False,\n       False, False, False, False, False, False, False])"
     },
     "metadata": {},
     "execution_count": 22
    }
   ],
   "source": [
    "2 * x == 24 - 4 * x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[ True,  True,  True,  True],\n       [ True,  True, False, False],\n       [False, False, False, False],\n       [False, False, False, False]])"
     },
     "metadata": {},
     "execution_count": 23
    }
   ],
   "source": [
    "X < 6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用 ``numpy.array`` 的比较结果 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "4"
     },
     "metadata": {},
     "execution_count": 24
    }
   ],
   "source": [
    "# 这个也可以求<=3的元素\n",
    "np.count_nonzero( x <= 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "4"
     },
     "metadata": {},
     "execution_count": 25
    }
   ],
   "source": [
    "# 求出有多少个<=3的元素\n",
    "np.sum(x <= 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([4, 0, 4, 0])"
     },
     "metadata": {},
     "execution_count": 26
    }
   ],
   "source": [
    "# 每一列有多少个偶数\n",
    "np.sum(X % 2 == 0, axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([2, 2, 2, 2])"
     },
     "metadata": {},
     "execution_count": 27
    }
   ],
   "source": [
    "# 每一行有多少个偶数\n",
    "np.sum(X % 2 == 0, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "True"
     },
     "metadata": {},
     "execution_count": 28
    }
   ],
   "source": [
    "# 是否有任意一个==0\n",
    "np.any(x == 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "False"
     },
     "metadata": {},
     "execution_count": 29
    }
   ],
   "source": [
    "# 是否有任意一个<0\n",
    "np.any(x < 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "False"
     },
     "metadata": {},
     "execution_count": 30
    }
   ],
   "source": [
    "np.all(x > 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "True"
     },
     "metadata": {},
     "execution_count": 31
    }
   ],
   "source": [
    "np.all(x >= 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([False,  True,  True,  True])"
     },
     "metadata": {},
     "execution_count": 32
    }
   ],
   "source": [
    "# 沿着列的方向，也就是看每一行是否都大于0\n",
    "np.all(X > 0, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "6"
     },
     "metadata": {},
     "execution_count": 33
    }
   ],
   "source": [
    "# 这个是位运算符。不是条件运算符。\n",
    "# 现在需要的是每一个数组进行独自运算，然后两个数组再合并，最后还是一个数组\n",
    "# 两个数组每一个元素看作一位，非常类似位运算符\n",
    "np.sum((x > 3) & (x < 10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-34-d834f65999a2>, line 1)",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-34-d834f65999a2>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    np.sum((x > 3) && (x < 10))\u001b[0m\n\u001b[1;37m                    ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "# 不是条件运算符\n",
    "# np.sum((x > 3) && (x < 10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "11"
     },
     "metadata": {},
     "execution_count": 35
    }
   ],
   "source": [
    "np.sum((x % 2 == 0) | (x > 10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "15"
     },
     "metadata": {},
     "execution_count": 36
    }
   ],
   "source": [
    "# 非运算\n",
    "np.sum(~(x == 0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 比较结果和Fancy Indexing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([ True,  True,  True,  True,  True, False, False, False, False,\n       False, False, False, False, False, False, False])"
     },
     "metadata": {},
     "execution_count": 37
    }
   ],
   "source": [
    "x < 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([0, 1, 2, 3, 4])"
     },
     "metadata": {},
     "execution_count": 38
    }
   ],
   "source": [
    "# <5的值到底是哪一些\n",
    "x[x < 5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([ 0,  2,  4,  6,  8, 10, 12, 14])"
     },
     "metadata": {},
     "execution_count": 39
    }
   ],
   "source": [
    "x[x % 2 == 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "[[ 0  1  2  3]\n [ 4  5  6  7]\n [ 8  9 10 11]\n [12 13 14 15]]\n[[ 0  1  2  3]\n [12 13 14 15]]\n[[ 0  1  2  3]\n [12 13 14 15]]\n"
    }
   ],
   "source": [
    "print(X)\n",
    "# 看每一行的索引为3的元素，能被3整除的行提取出来\n",
    "print(X[X[:,3] % 3 == 0, :])\n",
    "print(X[X[:,-1] % 3 == 0, :])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7-final"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}